﻿/* ==============================================================================
 * 功能描述：Map  
 * 
 * 创 建 者：郑镇泉
 * 
 * 创建日期：2016/4/17 21:54:41
 * ==============================================================================*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using LitJson;
using ZZQFrameWork;

[RequireComponent(typeof(AStar))]
public class Map : MonoBehaviour
{
    public static Map Instance;
    public int mapId;//地图id
    protected string mapName;//地图名称
    protected List<int> monsterIdList=new List<int>();//怪物ID集合
    [HideInInspector]
    public AStar aStar;

    private GameObject monsterParent;//怪物生成的父物体

    public GameObject MonsterParent
    {
        get {
            if (monsterParent==null)
            {
                monsterParent = GameObject.Find("Monster");
                if (monsterParent == null)
                {
                    monsterParent = new GameObject("Monster");
                }
            }
            return monsterParent;
        }
    }
    protected GameObject player;//玩家
    protected GameObject playerPrefab;//玩家预设体

    public Node[,] nodes;//所有node的集合
    protected TiledData map;//地图信息
    protected MapConfigMap MapConfig;//地图配置表

    public Vector2 offest;//偏移
    protected float size;//尺寸
    protected int width;//宽度
    protected List<int> roadList = new List<int>(); //道路集合
    protected int goodsId = 0;//生成物品的uid，包括怪物，宝箱，各类物品，自动分配uid

    void Awake()
    {
        Instance = this;
        playerPrefab = ResManager.Instance.Load("Player") as GameObject;
        aStar = GetComponent<AStar>();
        offest=new Vector2(-6.35f,6.35f);
        goodsId = 0;
    }

    public void InitMap(int mapId)
    {
        this.mapId = mapId;
        GameObject map = GameObject.Instantiate(ResManager.Instance.Load("MapBackground" + mapId) as GameObject);
        map.transform.SetParent(transform,false);
        MapConfig = MapConfigProvider.Instance.GetMapById(mapId);
        mapName = MapConfig.name;
        for (int i = 0; i < MapConfig.Monster.Length; i++)
        {
            monsterIdList.Add(int.Parse(MapConfig.Monster[i].id));
        }
        LoadMap();
    }

    void LoadMap()
    {
        map = JsonMapper.ToObject<TiledData>(MapManager.Instance.GetMap(mapName).text);
        width = map.width;
        size = 0.41f;
        nodes = new Node[map.width, map.height];
        //Debug.Log(map.layers.Count);
        OnLoadMap();
    }

    protected virtual void OnLoadMap()
    {
        for (int i = 0; i < map.layers.Count; i++)
        {
            //Debug.Log(map.layers[i].name);
            if (map.layers[i].name.Equals("Trigger"))
            {
                List<int> data = map.layers[i].data;
                for (int j = 0; j < data.Count; j++)
                {
                    int x = GetXByIndex(j);
                    int y = GetYByIndex(j);
                    Node node = new Node(x, y, GetPosByIndex(j));
                    //Debug.Log("x:"+node.x+"  y:"+node.y);
                    if (data[j] > 0)
                    {
                        //是障碍物
                        if (data[j] == map.GetTilesetsByName("Trigger").firstgid)
                        {
                            //CreatObj(pos, triggerPrefab);
                            node.canWalk = false;
                        }
                        else if (data[j] == map.GetTilesetsByName("Road").firstgid)
                        {
                            //CreatObj(pos, RoadPrefab);
                            roadList.Add(j);
                            node.canWalk = true;
                        }
                        else if (data[j] == map.GetTilesetsByName("Pass").firstgid)
                        {
                            //CreatObj(pos, passPrefab);
                            node.canWalk = true;
                            node.isPass = true;
                        }
                        else if (data[j] == map.GetTilesetsByName("Monster").firstgid)
                        {
                            LoadMonster(node);
                        }
                        else if (data[j] == map.GetTilesetsByName("Player").firstgid)
                        {
                            node.canWalk = true;
                            GameObject go = ResManager.Instance.Load("Player") as GameObject;
                            player = GameObject.Instantiate(go);

                            //player.GetComponent<PlayerAI>().map = this;
                            player.transform.position = GetPosByIndex(j);
                            node.goods = player;
                            Camera.main.transform.parent = player.transform;
                            Camera.main.transform.localPosition = new Vector3(0, 0, -1);
                        }
                    }
                    nodes[x, y] = node;
                }
            }
        }
    }

    /// <summary>
    /// 加载怪物
    /// </summary>
    /// <param name="node">加载怪物的node</param>
    protected virtual void LoadMonster(Node node)
    {
        Vector2 pos = node.pos;
        //int monsterId = RandomMonster(monsterIdList);
        int monsterId = 1;
        string monsterName = MonsterConfigProvider.Instance.GetMonsterById(monsterId).prefabName;
        GameObject obj = PoolManager.Instance.Spawn(monsterName);
        obj.transform.SetParent(MonsterParent.transform, false);

        MonsterVO monster = new MonsterVO(monsterId);
        monster.uid = goodsId;
        obj.GetComponent<MonsterAI>().Init(monster, pos, node);
        goodsId++;
    }

    /// <summary>
    /// 随机一个怪物
    /// </summary>
    /// <param name="monsters">怪物集合</param>
    /// <returns></returns>
    public int RandomMonster(List<int>monsters)
    {
        int index = UnityEngine.Random.Range(0, monsters.Count);
        return monsters[index];
    }

    /// <summary>
    /// 通过位置获取坐标
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    public Vector2 GetPosByIndex(int index)
    {
        int x=GetXByIndex(index);
        int y=GetYByIndex(index);

        return new Vector2((x + 1) * size, ((y + 1) * size) * -1) + offest;
    }

    /// <summary>
    /// 通过index获取x
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    protected int GetXByIndex(int index)
    {
        int x;
        if (index == 0)
        {
            x = 0;
        }
        else
        {
            if (index + 1 >= width)
            {
                x = index % width;
            }
            else
            {
                x = index;
            }
        }
        return x;
    }

    /// <summary>
    /// 通过index获取y
    /// </summary>
    /// <param name="index"></param>
    /// <returns></returns>
    protected int GetYByIndex(int index)
    {
        int y;
        if (index == 0)
        {
            y = 0;
        }
        else
        {
            y = index / width;
        }
        return y;
    }

    /// <summary>
    /// 通过坐标获取位置，会自动判断点击的坐标在哪个位置的格子里面
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public int GetIndexByPos(Vector2 pos)
    {

        float posX = (pos - offest).x;
        float posY = (pos - offest).y;
        //Debug.Log("点击点转换偏移后的位置："+posX+","+posY);
        float x = posX + size / 2;
        float y=Mathf.Abs(posY)+size/2;
        float a = x / size;
        float b = y / size;
        //Debug.Log("转换比例后的比例："+a+","+b);
        int index = ((int) a-1) + ((int) b-1)*width;
        //Debug.Log("获取位置："+index);
        return index;
    }

    /// <summary>
    /// 通过坐标获取node
    /// </summary>
    /// <param name="pos"></param>
    /// <returns></returns>
    public Node GetNodeByPos(Vector2 pos)
    {
        int index = GetIndexByPos(pos);
        return nodes[GetXByIndex(index), GetYByIndex(index)];
    }

    /// <summary>
    /// 通过xy获取index
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public int GetIndexByXY(int x, int y)
    {
        Debug.Log("查找index,"+x+":"+y);
        return y*width + x ;
    }

}